//    Copyright (C) Kherty.  All rights reserved.
using System;
using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Reflection;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using OpenLS.Spreadsheet.Drawing;
using OpenLS.Spreadsheet.UI.Internals;

namespace OpenLS.Spreadsheet.UI
{
    public partial class WorksheetPaneCellResources
    {
        public WorksheetPaneCellResources()
        {
            InitializeComponent();
        }
        internal Delegate _CreateDelegate(Type type, string name)
        {
            switch (name)
            {
                case "OnQueryCursor":
                    return new QueryCursorEventHandler(OnQueryCursor);
                    default: throw new NotSupportedException();
            }
        }

        void OnContentLoaded(object sender, RoutedEventArgs args)
        {
            var selectionControl = (ContentControl)sender;
            onLoadEditingLayer(selectionControl.Parent, null);
        }

        void onMouseWheel(object sender, MouseWheelEventArgs args)
        {
            var grid = (Grid)sender;
            var cp = (ContentPresenter)grid.TemplatedParent;
            UIElement wg = (WorksheetGrid)cp.ContentTemplate.FindName(ElementNames.EditingLayer, cp);
            GridEditing.OnMouseWheel(wg, args);
            

        }

        void onLoadEditingLayer(object sender, object args)
        {
            UIElement editingLayer = (WorksheetGrid)sender;
            if (SpreadsheetElement.GetWasLoaded(editingLayer))
                return;
            SpreadsheetElement.SetWasLoaded(editingLayer, true);
            editingLayer.GotFocus += onEditingLayerGotFocus;
            editingLayer.Focus();
            WorksheetPane pane = SpreadsheetElement.GetWorksheetPane(editingLayer);
            Worksheet worksheet = SpreadsheetElement.GetWorksheet(editingLayer);
            EnableCommands(editingLayer);
            if (worksheet.TopLeftPane == pane)
            {
                FrameworkElement element = (FrameworkElement) editingLayer;
                var parentElement = VisualTreeHelper.GetParent(element);
                var wb = SpreadsheetElement.GetWorkbook(element);
                if (wb != null)
                {
                    while (parentElement != null && SpreadsheetElement.GetWorkbook(parentElement) != null)
                    {
                        element = (FrameworkElement) parentElement;
                        parentElement = VisualTreeHelper.GetParent(element);
                    }
                    ForwardCommand(element, editingLayer);
                }
            }
        }

        private void ForwardCommand(FrameworkElement element, UIElement editingLayer)
        {
            foreach (CommandBinding commandBinding in editingLayer.CommandBindings)
            {
                if (!(commandBinding.Command is RoutedCommand))
                    continue;
                CommandBinding newBinding = new CommandBinding(commandBinding.Command);
                newBinding.Executed += delegate(object o, ExecutedRoutedEventArgs args)
                {
                    if (args.OriginalSource == editingLayer)
                    {
                        Debug.WriteLine("problem with can command " + ((args.Command is RoutedUICommand) ? ((RoutedUICommand)args.Command).Text : args.Command.ToString()));
                        //\\Contract.Assert((args.OriginalSource != editingLayer));
                        return;
                    }
                    RoutedCommand cmd = (RoutedCommand)args.Command;
                    cmd.Execute(args.Parameter, editingLayer);
                    args.Handled = true;
                };
                newBinding.CanExecute += delegate(object o, CanExecuteRoutedEventArgs args)
                {
                    //\\Contract.Assert((args.OriginalSource != editingLayer));
                    if (args.OriginalSource == editingLayer)
                    {
                     //\\   Debug.WriteLine("problem with can execute command " + ((args.Command is RoutedUICommand) ? ((RoutedUICommand)args.Command).Text : args.Command.ToString()));
                        return;
                    }
                    RoutedCommand cmd = (RoutedCommand)args.Command;
                    args.CanExecute = cmd.CanExecute(args.Parameter, editingLayer);
                   //\\ Contract.Assert(args.Handled, args.Command + " should handle command executed");

                    args.Handled = true;

                };
                element.CommandBindings.Add(newBinding);
            }
        }

        private static void EnableCommands(UIElement editingLayer)
        {
            GridKeyboardNavigation.EnableCommands(editingLayer);
            GridMouseSelection.EnableCommands(editingLayer);
            GridSelection.EnableCommands(editingLayer);
            GridClipboard.EnableCommands(editingLayer);
            // GridUndoRedo.EnableCommands(editingLayer);
            GridFormatting.EnableCommands(editingLayer);
            GridConditionalFormatting.EnableCommands(editingLayer);
            GridCalculations.EnableCommands(editingLayer);
            GridEditing.EnableCommands(editingLayer);
            GridFiltering.EnableCommands(editingLayer);
            DragDropManager.EnableEvents(editingLayer);
            WorksheetCharting.EnableCommands(editingLayer);
            GridBorders.EnableCommands(editingLayer);
            GridFormulaEditing.EnableCommands(editingLayer);
            // GridZooming.EnableCommands(editingLayer);
            GridUse.EnableCommands(editingLayer);
            GridFindReplace.EnableCommands(editingLayer);
            GridPanes.EnableCommands(editingLayer);
            GridComments.EnableCommands(editingLayer);
            GridGetData.EnableCommands(editingLayer);
            GridProtection.EnableCommands(editingLayer);
            GridValidation.EnableCommands(editingLayer);
            GridGrouping.EnableCommands(editingLayer);
            GridPageSetup.EnableCommands(editingLayer);
        }

        void onBringToFront(object sender, ExecutedRoutedEventArgs args)
        {
            var ic = (ItemsControl)sender;
            Worksheet worksheet = WorksheetHelper.GetWorksheet(sender);
            Anchor anchor = getAnchor(ic, args);
            args.Handled = true;
            if (worksheet.Anchors.Count <= 1)
                return;
            worksheet.Anchors.Move(worksheet.Anchors.IndexOf(anchor), worksheet.Anchors.Count - 1);
        }
        Anchor getAnchor(ItemsControl container, ExecutedRoutedEventArgs args)
        {
            if (args.Parameter is Anchor)
                return (Anchor)args.Parameter;
            return SpreadsheetElement.GetSelectedAnchor(container);
            //\\return (Anchor)container.Items.CurrentItem;
        }
        void onSendToBack(object sender, ExecutedRoutedEventArgs args)
        {
            var ic = (ItemsControl)sender;
            Worksheet worksheet = WorksheetHelper.GetWorksheet(sender);
            Anchor anchor = getAnchor(ic, args);
            args.Handled = true;
            if (worksheet.Anchors.Count <= 1)
                return;
            worksheet.Anchors.Move(worksheet.Anchors.IndexOf(anchor), 0);
        }
        void onSendBackward(object sender, ExecutedRoutedEventArgs args)
        {
            var ic = (ItemsControl)sender;
            Worksheet worksheet = WorksheetHelper.GetWorksheet(sender);
            Anchor anchor = getAnchor(ic, args);
            args.Handled = true;
            if (worksheet.Anchors.Count <= 1)
                return;
            int i = worksheet.Anchors.IndexOf(anchor);
            if (i == 0)
                return;
            worksheet.Anchors.Move(worksheet.Anchors.IndexOf(anchor), i - 1);
        }
        void onBringForward(object sender, ExecutedRoutedEventArgs args)
        {
            var ic = (ItemsControl)sender;
            Worksheet worksheet = WorksheetHelper.GetWorksheet(sender);
            Anchor anchor = getAnchor(ic, args);
            args.Handled = true;
            if (worksheet.Anchors.Count <= 1)
                return;
            int i = worksheet.Anchors.IndexOf(anchor);
            if (i >= worksheet.Anchors.Count - 1)
                return;
            worksheet.Anchors.Move(worksheet.Anchors.IndexOf(anchor), i + 1);
        }
        public void OnQueryCursor(object sender, QueryCursorEventArgs args) //\\ 
        {
            var grid = (WorksheetGrid)sender;
            if (grid.Columns == null)
                return;
            WorksheetPane p = WorksheetGrid.GetWorksheetPane(grid);
           //\\ Worksheet ws = grid.Columns.Worksheet;

            Point pt = args.MouseDevice.GetPosition((IInputElement)sender);
            CellAddress ca = p.GetCellAddressAt(pt);
            Cell cell = p.Worksheet.NonVolatileCells.GetItemIfAny(ca);
            if (cell != null && cell.Hyperlink != null)
            {
                args.Cursor = Cursors.Hand;
                args.Handled = true;
            }
        }

        static void onEditingLayerGotFocus(object sender, RoutedEventArgs args)
        {
            var grid = (WorksheetGrid) sender;
            FrameworkElement owner = EditionElement.GetWorkbookOwner(grid);
            EditionElement.SetFocusGrid(owner, grid);
        }

        private void mainGridLoaded(object sender, RoutedEventArgs e)
        {
            var grid = (Grid) sender;
            GridZooming.EnableCommands(grid);
            GridUndoRedo.EnableCommands(grid);
        }

    }
}
